﻿#region [ License information          ]
/* ************************************************************
 *
 * Copyright (c) Bjørn Bouet Smith, 2010, 2011
 *
 * This source code is subject to terms and conditions of 
 * Microsoft Public License (Ms-PL).
 * 
 * A copy of the license can be found in the license.txt
 * file at the root of this distribution. If you can not 
 * locate the License, please send an email to bjornsmith@gmail.com
 * 
 * By using this source code in any fashion, you are 
 * agreeing to be bound by the terms of the Microsoft 
 * Permissive License.
 *
 * You must not remove this notice, or any other, from this
 * software.
 *
 * ************************************************************/
#endregion

using System.Diagnostics;

namespace Smith.AMC.PerformanceCounters
{
    /// <summary>
    /// Class that handles installation of performance counters for the memcached client.
    /// Needs to be run by a user that have administrative rights on the local machine.
    /// </summary>
    public class PerformanceCounterInstaller
    {
        /// <summary>
        /// The name of the performance counter category
        /// </summary>
        public const string PerformanceCounterCategoryName = "Smith Async Memcached Client";

        /// <summary>
        /// Installs the performance counters on the local machine.
        /// </summary>
        public void Install()
        {
            DeleteExisting();
            CreateCategory();
        }

        /// <summary>
        /// Uninstalls the performance counters on the local machine
        /// </summary>
        public void Uninstall()
        {
            DeleteExisting();
        }

        /// <summary>
        /// Creates the specified performance counter creation data.
        /// </summary>
        /// <param name="name">The name of the performance counter.</param>
        /// <param name="description">The description.</param>
        /// <param name="counterType">Type of the counter.</param>
        /// <returns>A CounterCreationData object ready to be created.</returns>
        private static CounterCreationData Create(string name, string description, PerformanceCounterType counterType)
        {
            CounterCreationData creation = new CounterCreationData
                                               {
                                                   CounterHelp = description,
                                                   CounterName = name,
                                                   CounterType = counterType
                                               };
            return creation;
        }

        /// <summary>
        /// Deletes the existing performance counter category.
        /// </summary>
        private static void DeleteExisting()
        {
            if (PerformanceCounterCategory.Exists(PerformanceCounterCategoryName))
            {
                PerformanceCounterCategory.Delete(PerformanceCounterCategoryName);
            }
        }

        /// <summary>
        /// Creates the performance counter category and all the performance counters
        /// </summary>
        private static void CreateCategory()
        {
            CounterCreationDataCollection counters = new CounterCreationDataCollection();
            counters.AddRange(
                new[] 
                { 
                    Create(PerformanceCounterNames.AddsPerSecond, string.Empty, PerformanceCounterType.RateOfCountsPerSecond32),
                    Create(PerformanceCounterNames.AppendsPerSecond, string.Empty, PerformanceCounterType.RateOfCountsPerSecond32),
                    Create(PerformanceCounterNames.DecrementsPerSecond, string.Empty, PerformanceCounterType.RateOfCountsPerSecond32),
                    Create(PerformanceCounterNames.DeletesPerSecond, string.Empty, PerformanceCounterType.RateOfCountsPerSecond32),
                    Create(PerformanceCounterNames.ErrorsPerSecond, string.Empty, PerformanceCounterType.RateOfCountsPerSecond32),
                    Create(PerformanceCounterNames.GetsPerSecond, string.Empty, PerformanceCounterType.RateOfCountsPerSecond32),
                    Create(PerformanceCounterNames.IncrementsPerSecond, string.Empty, PerformanceCounterType.RateOfCountsPerSecond32),
                    Create(PerformanceCounterNames.PrependsPerSecond, string.Empty, PerformanceCounterType.RateOfCountsPerSecond32),
                    Create(PerformanceCounterNames.ReplacesPerSecond, string.Empty, PerformanceCounterType.RateOfCountsPerSecond32),
                    Create(PerformanceCounterNames.SetsPerSecond, string.Empty, PerformanceCounterType.RateOfCountsPerSecond32),
                    Create(PerformanceCounterNames.CASPerSecond, string.Empty, PerformanceCounterType.RateOfCountsPerSecond32),
                    Create(PerformanceCounterNames.AverageSocketWaitTime, string.Empty, PerformanceCounterType.AverageTimer32),
                    Create(PerformanceCounterNames.AverageSocketWaitTimeBase, string.Empty, PerformanceCounterType.AverageBase),
                    Create(PerformanceCounterNames.TotalCacheOperationsPerSecond, string.Empty, PerformanceCounterType.RateOfCountsPerSecond32),
                });

            PerformanceCounterCategory.Create(
                PerformanceCounterCategoryName, 
                "Performance counters for the Smith async memcached client", 
                PerformanceCounterCategoryType.SingleInstance, 
                counters);
        }
    }
}
